home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
(A)Z
/
(A)Z11.ADF
/
LOGO
/
LOGOSOURCE
/
logoop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-29
|
11KB
|
588 lines
/* Miscellaneous operations in LOGO.
* Copyright (C) 1979, The Children's Museum, Boston, Mass.
* Written by Douglas B. Klunder.
*/
#include "logo.h"
struct object *true()
{
return(localize(objcpstr("true")));
}
struct object *false()
{
return(localize(objcpstr("false")));
}
obstrcmp(obj,str)
register struct object *obj;
char *str;
{
if (!stringp(obj)) return(1);
return(strcmp(obj->obstr,str));
}
int truth(x) /* used by if handler in logo.y */
register struct object *x;
{
if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("If",x);
if (!obstrcmp(x,"true")) {
mfree(x);
return(1);
} else {
mfree(x);
return(0);
}
}
char *mkstring(obj)
register struct object *obj;
{
/* subroutine for several operations which treat numbers as words,
* turn number into character string.
* Note: obj must be known to be nonempty; result is ptr to static.
*/
register char *cp;
static char str[30];
switch(obj->obtype) {
case STRING:
cp = obj->obstr;
break;
case INT:
sprintf(str,FIXFMT,obj->obint);
cp = str;
break;
case DUB:
sprintf(str,"%g",obj->obdub);
if (!index(str,'.')) strcat(str,".0");
cp = str;
break;
default: /* case CONS */
return(0); /* not a string, handle uplevel */
}
return(cp);
}
struct object *and(x,y) /* both */
register struct object *x,*y;
{
if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("Both",x);
if (obstrcmp(y,"true") && obstrcmp(y,"false")) ungood("Both",y);
if (!obstrcmp(x,"true")) {
mfree(x);
return(y);
} else {
mfree(y);
return(x);
}
}
struct object *or(x,y) /* either */
register struct object *x,*y;
{
if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("Either",x);
if (obstrcmp(y,"true") && obstrcmp(y,"false")) ungood("Either",y);
if (!obstrcmp(x,"true")) {
mfree(y);
return(x);
} else {
mfree(x);
return(y);
}
}
emptyp(x) /* non-LOGO emptyp, returning 1 if empty, 0 if not. */
register struct object *x;
{
if (x==0) return(1);
switch (x->obtype) {
case STRING:
if (*(x->obstr)=='\0') /* check for character */
return(1);
default:
return(0);
}
}
struct object *lemp(x) /* LOGO emptyp */
register struct object *x;
{
if (emptyp(x)) {
mfree(x);
return(true());
} else {
mfree(x);
return(false());
}
}
struct object *comp(x) /* not */
register struct object *x;
{
if (!obstrcmp(x,"true")) {
mfree(x);
return(false());
} else if (!obstrcmp(x,"false")) {
mfree(x);
return(true());
} else ungood("Not",x);
}
struct object *lsentp(x) /* LOGO sentencep */
register struct object *x;
{
register struct object *y;
if (x==0) return(true());
if (listp(x)) {
/* BH 4/30/81 true only for a flat sentence,
not a list of lists */
for (y = x; y; y = y->obcdr)
if (listp(y->obcar)) {
mfree(x);
return(false());
}
mfree(x);
return(true());
} else {
mfree(x);
return(false());
}
}
struct object *lwordp(x) /* LOGO wordp */
register struct object *x;
{
if (!listp(x)) {
mfree(x);
return(true());
} else {
mfree(x);
return(false());
}
}
struct object *first(x) /* first */
register struct object *x;
{
register struct object *temp;
register char *cp;
char str[2];
if (emptyp(x)) ungood("First",x);
if (cp = mkstring(x)) {
str[0] = *cp;
str[1] = '\0';
mfree(x);
return(localize(objcpstr(str)));
} else {
temp = x->obcar;
localize(temp);
mfree(x);
return(temp);
}
}
struct object *butfir(x) /* butfirst */
register struct object *x;
{
register struct object *temp;
register char *cp;
if (emptyp(x)) ungood("Butfirst",x);
if (cp = mkstring(x)) {
cp++; /* skip first char */
mfree(x);
return(localize(objcpstr(cp)));
} else {
temp = x->obcdr;
localize(temp);
mfree(x);
return(temp);
}
}
struct object *last(x) /* last */
register struct object *x;
{
register struct object *temp;
register char *cp;
if (emptyp(x)) ungood("Last",x);
if (cp = mkstring(x)) {
mfree(x);
return(localize(objcpstr(&cp[strlen(cp)-1])));
} else {
for(temp=x; temp->obcdr; temp=temp->obcdr) ;
temp = temp->obcar;
localize(temp);
mfree(x);
return(temp);
}
}
struct object *butlas(x) /* butlast */
register struct object *x;
{
register struct object *temp,*temp2,*ans;
register char *cp;
if (emptyp(x)) ungood("Butlast",x);
if (cp = mkstring(x)) {
mfree(x);
temp = objstr(ckmalloc(strlen(cp)));
strncpy(temp->obstr,cp,strlen(cp)-1);
(temp->obstr)[strlen(cp)-1] = '\0';
return(localize(temp));
} else {
if ((x->obcdr)==0) {
mfree(x);
return(0);
}
temp2 = ans = globcons(0,0);
for(temp=x; temp->obcdr->obcdr; temp=temp->obcdr) {
temp2->obcar = globcopy(temp->obcar);
temp2->obcdr = globcopy(globcons(0,0));
temp2 = temp2->obcdr;
}
temp2->obcar = globcopy(temp->obcar);
localize(ans);
mfree(x);
return(ans);
}
}
struct object *fput(x,y)
register struct object *x,*y;
{
register struct object *z;
if(!listp(y)) {
printf("Second input of fput must be a list.\n");
errhand();
}
z = loccons(x,y);
mfree(x);
mfree(y);
return(z);
}
struct object *lput(x,y)
struct object *x,*y;
{
register struct object *a,*b,*ans;
if (!listp(y)) {
printf("Second input of lput must be a list.\n");
errhand();
}
if (y == 0) { /* 2nd input is empty list */
b = loccons(x,0);
mfree(x);
return(b);
}
ans = a = loccons(0,0);
for (b=y; b; b=b->obcdr) {
a->obcar = globcopy(b->obcar);
a->obcdr = globcopy(globcons(0,0));
a = a->obcdr;
}
a->obcar = globcopy(x);
mfree(x);
mfree(y);
return(ans);
}
struct object *list(x,y)
struct object *x,*y;
{
register struct object *a,*b;
b = globcons(y,0);
a = loccons(x,b);
mfree(x);
mfree(y);
return(a);
}
struct object *length(x) /* count */
register struct object *x;
{
register struct object *temp;
register char *cp;
register int i;
if (x==0) return(localize(objint((FIXNUM)0)));
if (cp = mkstring(x)) {
i = strlen(cp);
mfree(x);
return(localize(objint((FIXNUM)i)));
} else {
i = 0;
for (temp=x; temp; temp = temp->obcdr)
i++;
mfree(x);
return(localize(objint((FIXNUM)i)));
}
}
logois(x,y) /* non-Logo is, despite the name */
register struct object *x,*y;
{
if (listp(x)) {
if (listp(y)) {
if (x==0) return(y==0);
if (y==0) return(0);
return(logois(x->obcar,y->obcar) &&
logois(x->obcdr,y->obcdr) );
}
return(0);
}
if (listp(y)) return(0);
if (x->obtype != y->obtype) return(0);
switch (x->obtype) {
case INT:
return(x->obint == y->obint);
case DUB:
return(x->obdub == y->obdub);
default: /* case STRING */
return(!strcmp(x->obstr,y->obstr));
}
}
struct object *lis(x,y)
register struct object *x,*y;
{
register z;
z = logois(x,y);
mfree(x);
mfree(y);
return(z ? true() : false());
}
leq(x,y) /* non-Logo numeric equal */
register struct object *x,*y;
{
NUMBER dx,dy;
FIXNUM ix,iy;
int xint,yint;
if (listp(x) || listp(y)) return(logois(x,y));
if (stringp(x) && !nump(x)) return(logois(x,y));
if (stringp(y) && !nump(y)) return(logois(x,y));
xint = yint = 0;
if (stringp(x)) {
if (isint(x)) {
xint++;
sscanf(x->obstr,FIXFMT,&ix);
} else {
sscanf(x->obstr,EFMT,&dx);
}
} else {
if (intp(x)) {
xint++;
ix = x->obint;
} else {
dx = x->obdub;
}
}
if (stringp(y)) {
if (isint(y)) {
yint++;
sscanf(y->obstr,FIXFMT,&iy);
} else {
sscanf(y->obstr,EFMT,&dy);
}
} else {
if (intp(y)) {
yint++;
iy = y->obint;
} else {
dy = y->obdub;
}
}
if (xint != yint) {
if (xint) dx = ix;
else dy = iy;
xint = 0;
}
if (xint)
return (ix == iy);
else
return (dx == dy);
}
struct object *equal(x,y) /* Logo equalp */
register struct object *x,*y;
{
register z;
z = leq(x,y);
mfree(x);
mfree(y);
return(z ? true() : false());
}
struct object *worcat(x,y) /* word */
register struct object *x,*y;
{
char *val,*xp,*yp;
char xstr[30],ystr[30];
if (listp(x)) ungood("Word",x);
if (listp(y)) ungood("Word",y);
switch(x->obtype) {
case INT:
sprintf(xstr,FIXFMT,x->obint);
xp = xstr;
break;
case DUB:
sprintf(xstr,"%g",x->obdub);
if (!index(xstr,'.')) strcat(xstr,".0");
xp = xstr;
break;
default: /* case STRING */
xp = x->obstr;
}
switch(y->obtype) {
case INT:
sprintf(ystr,FIXFMT,y->obint);
yp = ystr;
break;
case DUB:
sprintf(ystr,"%g",y->obdub);
if (!index(ystr,'.')) strcat(ystr,".0");
yp = ystr;
break;
default: /* case STRING */
yp = y->obstr;
}
val=ckmalloc(strlen(xp)+strlen(yp)+1);
cpystr(val,xp,yp,NULL);
mfree(x);
mfree(y);
return(localize(objstr(val)));
}
struct object *sencat(x,y) /* sentence */
struct object *x,*y;
{
register struct object *a,*b,*c;
if (x==0) {
if (listp(y)) return(y);
a = loccons(y,0);
mfree(y);
return(a);
}
if (listp(x)) {
c = a = globcons(0,0);
for (b=x; b->obcdr; b = b->obcdr) {
a->obcar = globcopy(b->obcar);
a->obcdr = globcopy(globcons(0,0));
a = a->obcdr;
}
a->obcar = globcopy(b->obcar);
}
else c = a = globcons(x,0);
if (listp(y)) b = y;
else b = globcons(y,0);
a->obcdr = globcopy(b);
mfree(x);
mfree(y);
return(localize(c));
}
struct object *memberp(thing,group)
struct object *thing,*group;
{
register char *cp;
register struct object *rest;
int i;
if (group==0) {
mfree(thing);
return(false());
}
if (cp = mkstring(group)) {
if (thing==0) {
mfree(group);
return(false());
}
switch (thing->obtype) {
case INT:
if((thing->obint >= 0)&&(thing->obint < 10)) {
i = memb('0'+thing->obint,cp);
break;
}
case CONS:
case DUB:
i = 0;
break;
default: /* STRING */
if (strlen(thing->obstr) == 1) {
i = memb(*(thing->obstr),cp);
} else i = 0;
}
} else {
i = 0;
for (rest=group; rest; rest=rest->obcdr) {
if (leq(rest->obcar,thing)) {
i++;
break;
}
}
}
mfree(thing);
mfree(group);
return(torf(i));
}
struct object *item(num,group)
struct object *num,*group;
{
int inum,ernum;
register char *cp;
register struct object *rest;
char str[2];
num = numconv(num,"Item");
if (intp(num)) inum = num->obint;
else inum = num->obdub;
if (inum <= 0) ungood("Item",num);
if (group == 0) ungood("Item",group);
if (cp = mkstring(group)) {
if (inum > strlen(cp)) {
pf1("%p has fewer than %d items.\n",group,inum);
errhand();
}
str[0] = cp[inum-1];
str[1] = '\0';
mfree(num);
mfree(group);
return(localize(objcpstr(str)));
} else {
ernum = inum;
for (rest = group; --inum; rest = rest->obcdr) {
if (rest==0) break;
}
if (rest==0) {
pf1("%p has fewer than %d items.\n",
group,ernum);
errhand();
}
mfree(num);
rest = localize(rest->obcar);
mfree(group);
return(rest);
}
}